package com.truyen.persistence.dao.impl;

import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;

import com.truyen.persistence.dao.AccountDao;
import com.truyen.persistence.dao.base.GenericJpaBaseDaoImpl;
import com.truyen.persistence.entity.Account;
import com.truyen.utils.PagingInfo;

@Repository
public class AccountDaoImpl extends GenericJpaBaseDaoImpl<Account, Long>
		implements AccountDao {

	public AccountDaoImpl() {
		super(Account.class);
	}

	@Override
	public boolean checkExist(String email) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Account> cq = cb.createQuery(Account.class);
		Root<Account> entity = cq.from(Account.class);

		cq = cq.where(cb.equal(entity.get("email"), email));
		long count = countByQuery(cq, entity);

		return count > 0;
	}

	@Override
	public List<Account> getUsers(String kw, PagingInfo pInfo) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Account> query = critBuilder
				.createQuery(Account.class);
		Root<Account> entity = query.from(Account.class);
		Predicate p = critBuilder.conjunction();
		if(kw != null && !kw.equals("")){
			String kwTemp = "%" + kw + "%";
			p = critBuilder.and(p,
						critBuilder.or(
							critBuilder.like(entity.<String>get("email"), kwTemp),
							critBuilder.like(entity.<String>get("address"), kwTemp),
							critBuilder.like(entity.<String>get("city"), kwTemp),
							critBuilder.like(entity.<String>get("dayReg"), kwTemp),
							critBuilder.like(entity.<String>get("fullName"), kwTemp),
							critBuilder.like(entity.<String>get("mobile"), kwTemp)));
		}
		query = query.where(p);
		TypedQuery<Account> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		pInfo.setTotalPage((int)Math.ceil((double)count/pInfo.getSizePerPage()));		
		q.setFirstResult(pInfo.getStartResult());
		q.setMaxResults(pInfo.getSizePerPage());
		List<Account> lst = q.getResultList();
		return lst;
	}

	@Override
	public List<Account> getAllLst(String kwSearch, String sort, String sortBy,
			PagingInfo pInfo) {
		CriteriaBuilder critBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Account> query = critBuilder
				.createQuery(Account.class);
		Root<Account> entity = query.from(Account.class);
		Predicate p = critBuilder.conjunction();
		if(kwSearch!=null && !kwSearch.equals("")){
			kwSearch = kwSearch + "%";
			p = critBuilder.and(p,
					critBuilder.like(entity.<String> get("email"), kwSearch));
			p = critBuilder.or(p,
					critBuilder.like(entity.<String> get("fullName"), kwSearch),
					critBuilder.like(entity.<String> get("nickName"), "%" + kwSearch),
					critBuilder.like(entity.<String> get("mobile"), "%" + kwSearch));
		}
		query = query.where(p);
		if(sort.equals("desc")){
			query.orderBy(critBuilder.desc(entity.get(sortBy)));
		}else{
			query.orderBy(critBuilder.asc(entity.get(sortBy)));
		}
		TypedQuery<Account> q = entityManager.createQuery(query);
		long count = countByQuery(query, entity);
		pInfo.setCount(count);
		pInfo.setTotalPage((int)Math.ceil((double)count/pInfo.getSizePerPage()));		
		q.setFirstResult(pInfo.getStartResult());
		q.setMaxResults(pInfo.getSizePerPage());
		List<Account> lst = q.getResultList();
		return (lst.size() > 0) ? lst : null;
	}
}
